package com.gamefx.fte
{
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.net.URLRequest;
	import flash.net.navigateToURL;
	import flash.text.engine.ContentElement;
	import flash.text.engine.GroupElement;
	import flash.text.engine.TextElement;
	import flash.text.engine.TextLine;
	import flash.utils.Dictionary;
	
	import mx.core.IDataRenderer;
	import mx.core.UIComponent;

	/**
	 *  当点击链接文本时触发
	 *
	 *  @eventType com.tming.rpgcorelib.fte.TextComponentEvent.ITEM_CLICK
	 */
	[Event(name="item_click", type="com.tming.rpgcorelib.fte.TextComponentEvent")]

	/**
	 * 基于FTE的文本组件，支持图文混排， 支持多级HTML
	 *
	 * 设置linkEnable为true，则可支持a标签的鼠标事件接收，动画表现为绘制下划线
	 *
	 * @notice 所有HTML标签必须闭合，HTML标签支持范围见TextConverter
	 * @notice 默认autoSize=true(width表现为maxWidth), 要设置固定宽度，请设置autoSize=false
	 * 
	 * @author feather
	 * 
	 */
	public class TextComponent extends UIComponent implements IDataRenderer
	{
		//--------------------------------------------------------------------------
		//
		//  Class properties
		//
		//--------------------------------------------------------------------------

		//--------------------------------------------------------------------------
		//
		//  Constructor
		//
		//--------------------------------------------------------------------------

		public function TextComponent()
		{
			super();
			mouseEnabled = false;
			_baseContent = new TextBase();
			addChild(_baseContent);
		}

		//--------------------------------------------------------------------------
		//
		//  Variables
		//
		//--------------------------------------------------------------------------

		public var color:uint = 0x000000;
		public var fontSize:int = 12;
		public var fontName:String = "宋体,_serif";
		public var fontWeight:String = "normal";
		public var fontPosture:String = "normal";
		public var leading:int = 3;

		protected var _elements:Vector.<ContentElement>;
		protected var _cellDict:Dictionary;
		protected var _activeShape:Shape;

		//----------------------------------
		//  data
		//----------------------------------
		
		protected var _data:Object;
		
		public function get data():Object
		{
			return _data;
		}
		
		public function set data(value:Object):void
		{
			_data = value;
		}
		
		//----------------------------------
		//  baseContent
		//----------------------------------

		protected var _baseContent:TextBase;

		public function get baseContent():TextBase
		{
			return _baseContent;
		}

		//----------------------------------
		//  linkEnabled
		//----------------------------------

		protected var _linkEnabled:Boolean;

		public function get linkEnabled():Boolean
		{
			return _linkEnabled;
		}

		public function set linkEnabled(value:Boolean):void
		{
			_linkEnabled = value;
			
			if (_baseContent.initialized)
				createChildren();
		}

		//----------------------------------
		//  htmlText
		//----------------------------------

		protected var _htmlText:String;

		public function get htmlText():String
		{
			return _htmlText;
		}

		public function set htmlText(value:String):void
		{
			_htmlText = value;
			
			if (value != null && value.length != 0)
			{
				if (value.indexOf("<p>") != 0 || value.indexOf("<P>") != 0) //简单处理没有被<p>包围的文本
				{
					value = "<p>" + value + "</p>";
				}
				
				_elements = TextConverter.conver(value, {color: color, fontSize: fontSize, fontName: fontName, fontWeight: fontWeight, fontPosture: fontPosture});
				_baseContent.content = (_elements.length == 1) ? _elements[0] : new GroupElement(_elements);
			}
			else
			{
				_baseContent.content = null;
			}
			
			if (_baseContent.initialized)
				createChildren();
		}

		//----------------------------------
		//  width
		//----------------------------------

		override public function set width(value:Number):void
		{
			super.width = _baseContent.width = value;
			
			if (_baseContent.initialized)
				createChildren();
		}
		
		//----------------------------------
		//  autoSize
		//----------------------------------
		
		public function get autoSize():Boolean
		{
			return _baseContent.autoSize;
		}
		
		public function set autoSize(value:Boolean):void
		{
			_baseContent.autoSize = value;
			
			if (_baseContent.initialized)
				createChildren();
		}

		//--------------------------------------------------------------------------
		//
		//  Methods
		//
		//--------------------------------------------------------------------------

		public function destory():void
		{
			_baseContent.destory();
			_cellDict = null;
			_elements = null;
			_activeShape = null;
		}

		override protected function createChildren():void
		{
			if (_cellDict != null)
			{
				for (var cell:* in _cellDict)
				{
					cell.removeEventListener(MouseEvent.ROLL_OVER, cellRollOverHandler);
					cell.removeEventListener(MouseEvent.ROLL_OUT, cellRollOutHandler);
					cell.removeEventListener(MouseEvent.CLICK, cellClickHandler);
					if (contains(cell))
						removeChild(cell);
				}
			}
			
			_baseContent.leading = leading;
			_baseContent.initialize();
			
			super.width = _baseContent.width;
			super.height = _baseContent.height < minHeight ? minHeight : _baseContent.height;
			
			if (_linkEnabled && _baseContent.content != null) //允许激活超链接时，绘制接收鼠标事件单元
				drawCells();
		}

		/**
		 * 绘制透明的Sprite，用于接收鼠标事件。并记录下划线的绘制区域。
		 */ 
		protected function drawCells():void
		{
			_cellDict = new Dictionary(true); //记录cell需要的额外属性

			var dataDict:Dictionary = new Dictionary(true); //数据字典，拥有相同数据(userData.data)的多个contentElement，使用同一个cell，以便同时响应鼠标事件
			var pathData:Array;
			var contentElement:ContentElement;
			var textlineIndexDict:Dictionary;
			var cell:Sprite;
			var index:int;
			var beginTextline:TextLine;
			var beginBounds:Rectangle;
			var endTextline:TextLine;
			var endBounds:Rectangle;
			var centerHeight:int;
			var last:String;
			for each (contentElement in _elements)
			{
				if (contentElement.userData != null && contentElement.userData.data != null)
				{
					cell = dataDict[contentElement.userData.data];
					if (cell == null)
					{
						dataDict[contentElement.userData.data] = cell = new Sprite();
						pathData = [];
						_cellDict[cell] = {data: contentElement.userData.data, text: contentElement.text, path: pathData};
					}
					else
					{
						pathData = _cellDict[cell].path;
						_cellDict[cell].text += contentElement.text;
					}

					if (textlineIndexDict == null) //计算所有行的起始字符的位置
						textlineIndexDict = clacTextlinesBeginIndex();

					index = contentElement.textBlockBeginIndex;
					beginTextline = contentElement.textBlock.getTextLineAtCharIndex(index);
					beginBounds = beginTextline.getAtomBounds(index - textlineIndexDict[beginTextline]);

					if (!(contentElement is TextElement) || contentElement.text.length <= 1) //图像
					{
						with (cell.graphics)
						{
							beginFill(0, 0);
							drawRect(beginBounds.x, beginTextline.y + beginBounds.y, beginBounds.width, beginBounds.height);
							endFill();
						}
						//记录下划线位置
						pathData.push([contentElement.elementFormat.color, beginBounds.x, beginTextline.y, beginBounds.width]);
					}
					else
					{
						index = index + contentElement.text.length - 1;
						endTextline = contentElement.textBlock.getTextLineAtCharIndex(index);
						endBounds = endTextline.getAtomBounds(index - textlineIndexDict[endTextline]);

						if (beginTextline == endTextline) //单行
						{
							with (cell.graphics)
							{
								beginFill(0, 0);
								drawRect(beginBounds.x, beginTextline.y + beginBounds.y, endBounds.x - beginBounds.x + endBounds.width, beginBounds.height);
								endFill();
							}
							//记录下划线位置
							pathData.push([contentElement.elementFormat.color, beginBounds.x, beginTextline.y, endBounds.x + endBounds.width - beginBounds.x]);
						}
						else //多行
						{
							with (cell.graphics)
							{
								beginFill(0, 0);
								drawRect(beginBounds.x, beginTextline.y + beginBounds.y, beginTextline.width - beginBounds.x, beginBounds.height); //第一行

								centerHeight = endTextline.y - endTextline.height - beginTextline.y;
								if (centerHeight > 1)
									drawRect(0, beginTextline.y, beginTextline.width, endTextline.y - endTextline.height - beginTextline.y); //中间行

								drawRect(0, endTextline.y + endBounds.y, endBounds.x + endBounds.width, endBounds.height); //最后一行
								endFill();
							}
							//记录下划线位置
							pathData.push([contentElement.elementFormat.color, beginBounds.x, beginTextline.y, beginTextline.width - beginBounds.x]);
							beginTextline = beginTextline.nextLine;
							while (beginTextline != endTextline)
							{
								pathData.push([contentElement.elementFormat.color, 0, beginTextline.y, beginTextline.width]);
								beginTextline = beginTextline.nextLine;
							}
							pathData.push([contentElement.elementFormat.color, 0, endTextline.y, endBounds.x + endBounds.width]);
						}
					}

					cell.buttonMode = true;
					cell.mouseChildren = false;
					cell.addEventListener(MouseEvent.ROLL_OVER, cellRollOverHandler, false, 0, true);
					cell.addEventListener(MouseEvent.ROLL_OUT, cellRollOutHandler, false, 0, true);
					cell.addEventListener(MouseEvent.CLICK, cellClickHandler, false, 0, true);
					addChild(cell);
				}
			}
		}

		protected function clacTextlinesBeginIndex():Dictionary
		{
			var dict:Dictionary = new Dictionary(true);
			var textline:TextLine = _baseContent.textBlock.firstLine;
			var index:int = 0;
			while (textline != null)
			{
				dict[textline] = index;
				index += textline.atomCount;
				textline = textline.nextLine;
			}
			return dict;
		}

		//--------------------------------------------------------------------------
		//
		//  Event handlers
		//
		//--------------------------------------------------------------------------

		protected function cellRollOverHandler(event:MouseEvent):void
		{
			var cellData:Object = _cellDict[event.target];
			if (cellData == null)
				return;

			if (_activeShape == null)
			{
				_activeShape = new Shape();
				addChild(_activeShape);
			}

			// 绘制下划线
			var arr:Array;
			with (_activeShape.graphics)
			{
				clear();
				for each (arr in cellData.path)
				{
					beginFill(arr[0]);
					drawRect(arr[1], arr[2] + 1, arr[3], 1);
				}
				endFill();
			}
		}

		protected function cellRollOutHandler(event:MouseEvent):void
		{
			if (_activeShape != null)
			{
				_activeShape.graphics.clear();
			}
		}

		protected function cellClickHandler(event:MouseEvent):void
		{
			var cellData:Object = _cellDict[event.target];
			if (cellData == null || cellData.data == null)
				return;

			var href:String = cellData.data.href;
			if (href.indexOf("event:") == 0)
			{
				dispatchEvent(new TextComponentEvent(TextComponentEvent.ITEM_CLICK, cellData.text, href.slice(6)));
			}
			else
			{
				navigateToURL(new URLRequest(href), '_blank');
			}
		}

	}
}